package com.ruoyi.web.controller.system;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.UserDetailsServiceImpl;
import com.ruoyi.system.mapper.H5RegisterMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.web.controller.sso.zhgx.oauth2.model.OupAuth2Token;
import com.ruoyi.web.controller.sso.zhgx.oauth2.model.OupAuth2TokenDto;
import com.ruoyi.web.controller.sso.zhgx.oauth2.model.OupAuth2TokenUserInfo;
import com.ruoyi.web.controller.sso.zhgx.oauth2.properties.Oauth2Properties;
import com.ruoyi.web.controller.sso.zhgx.oauth2.response.company.CompanyInfo;
import com.ruoyi.web.controller.sso.zhgx.oauth2.response.company.CompanyRecordsDto;
import com.ruoyi.web.controller.sso.zhgx.oauth2.response.corporation.Corporation;
import com.ruoyi.web.controller.sso.zhgx.oauth2.response.user.UserInfo;
import com.ruoyi.web.controller.sso.zhgx.oauth2.response.user.UserInfoRes;
import com.ruoyi.web.domain.SysArea;
import com.ruoyi.web.domain.dto.AiShanDongUserEncodeInfoDto;
import com.ruoyi.web.service.SysAreaService;
import com.ruoyi.web.service.impl.AiShanDongSsoServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * 登录验证
 * 
 * @author ruoyi
 */
@RestController
public class SysLoginController
{
    private final Logger logger = LoggerFactory.getLogger(SysLoginController.class);

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysAreaService sysAreaService;

    @Autowired
    private AiShanDongSsoServiceImpl aiShanDongSsoService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private Oauth2Properties oauth2Properties;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private H5RegisterMapper h5RegisterMapper;

    @Autowired
    private CloseableHttpClient closeableHttpClient;

    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid(), "");
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }


    /**
     * 爱山东侧登录 - 自动登录
     */
    @PostMapping("/automaticLogin")
    public AjaxResult automaticLogin(@RequestBody AiShanDongUserEncodeInfoDto dto)
    {
        return aiShanDongSsoService.ssoLogin(dto);
    }

    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        String province = user.getProvince();
        String city = user.getCity();
        String district = user.getDistrict();
        if (StringUtils.isNotBlank(province) && StringUtils.isNotBlank(city) && StringUtils.isNotBlank(district)) {
            List<String> areaCodeList = Arrays.asList(province, city, district);
            List<SysArea> areaList = sysAreaService.list(new LambdaQueryWrapper<SysArea>().in(SysArea::getCode, areaCodeList));
            user.setProvinceName(areaList.get(0).getName());
            user.setCityName(areaList.get(1).getName());
            user.setDistrictName(areaList.get(2).getName());
        }
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        if (!loginUser.getPermissions().equals(permissions))
        {
            loginUser.setPermissions(permissions);
            tokenService.refreshToken(loginUser);
        }
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }

    /**
     * 新版智慧工信对接接口
     */
    @GetMapping("/callbackNew")
    public R<?> callBackNew(@RequestParam(value = "code") String code) throws IOException {

        String getTokenUrl = UriComponentsBuilder.fromUriString(oauth2Properties.getTokenUrl())
                .queryParam("grant_type", "authorization_code")
                .queryParam("client_id", oauth2Properties.getAppId())
                .queryParam("client_secret", oauth2Properties.getAppSecret())
                .queryParam("redirect_uri", URLEncoder.encode(oauth2Properties.getRedirectUrl(), "UTF-8"))
                .queryParam("code", code)
                .build()
                .toUriString();

        HttpGet httpGet = new HttpGet(getTokenUrl);
        try (CloseableHttpResponse tokenRes = closeableHttpClient.execute(httpGet)) {
            int statusCode = tokenRes.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                String tokenResResult = EntityUtils.toString(tokenRes.getEntity());
                OupAuth2Token oupAuth2Token = objectMapper.readValue(tokenResResult, OupAuth2Token.class);
                String accessToken = oupAuth2Token.getAccessToken();
                OupAuth2TokenUserInfo userInfo = oupAuth2Token.getUserInfo();
                if (userInfo != null && com.ruoyi.common.utils.StringUtils.equals("2", userInfo.getUserType())) {
                    // 如果是法人登陆，获取该法人名下的企业信息
                    HttpGet httpGet1 = new HttpGet(oauth2Properties.getUserInfoUrl());
                    httpGet1.setHeader("Authorization", "Bearer " + accessToken);

                    try (CloseableHttpResponse userInfoRes = closeableHttpClient.execute(httpGet1)) {
                        int userInfoResStatus = userInfoRes.getStatusLine().getStatusCode();
                        String userInfoResResult = EntityUtils.toString(userInfoRes.getEntity());

                        UserInfoRes userInfoResp = JSONObject.parseObject(userInfoResResult, UserInfoRes.class);

//                        logger.error("userInfo：{}", userInfoResp);
                        if (userInfoResStatus == 200) {
                            UserInfo data = userInfoResp.getData();
                            if(data != null) {
                                Corporation corporation = data.getCorporation();
                                if(corporation != null) {
                                    CompanyInfo companyInfo = new CompanyInfo();
                                    companyInfo.setCornumber(corporation.getCorCode());
                                    companyInfo.setCorname(corporation.getCorName());
                                    companyInfo.setToken(accessToken);
                                    companyInfo.setUserType("2");
                                    List<CompanyInfo> list = Arrays.asList(companyInfo);
                                    CompanyRecordsDto companyRecords = new CompanyRecordsDto();
                                    companyRecords.setRecords(list);
                                    companyRecords.setUserInfo(userInfo);
//                                    logger.error("返回结果为：{}", companyRecords);
                                    return R.ok(companyRecords);
                                } else {
                                    return R.fail("获取企业数据失败");
                                }
                            } else {
                                return R.fail("获取企业数据失败");
                            }
                        } else {
                            return R.fail("获取企业数据失败");
                        }
                    } catch (Exception e) {
                        return R.fail("获取企业数据失败:{}", e.toString());
                    }
                } else if (userInfo != null && com.ruoyi.common.utils.StringUtils.equals("0", userInfo.getUserType())) {
                    // 厅内人员登陆，直接返回列表
                    List<CompanyInfo> p = new ArrayList<>();
                    CompanyInfo c = new CompanyInfo();
                    c.setCorname(userInfo.getZwfwUuid());
                    c.setCornumber(userInfo.getUsername());
                    c.setToken(accessToken);
                    c.setUserType("0");
                    p.add(c);

                    CompanyRecordsDto companyRecords = new CompanyRecordsDto();
                    companyRecords.setRecords(p);
                    companyRecords.setUserInfo(userInfo);

                    return R.ok(companyRecords);
                } else if (userInfo != null && com.ruoyi.common.utils.StringUtils.equals("1", userInfo.getUserType())) {
                    return R.fail("请使用法人账号登陆");
                }
                return R.fail("认证失败");
            } else {
                return R.fail("认证失败");
            }
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    /**
     * 新版智慧工信对接 - 授权登录接口
     */
    @PostMapping("qwwqplvdngNew")
    public AjaxResult loginNew(@RequestBody OupAuth2TokenDto dto) throws IOException {

        OupAuth2TokenUserInfo tokenUserInfo = dto.getUserInfo();
        String zwfwUuid;
        String username;
        if (tokenUserInfo != null) {
            zwfwUuid = tokenUserInfo.getZwfwUuid();
            username = dto.getCorCode();
            int id = tokenUserInfo.getId();
            if (StringUtils.isBlank(zwfwUuid)) {
                zwfwUuid = id + "";
            }

            if (StringUtils.isBlank(username)) {
                username = tokenUserInfo.getUsername();
            }

            if (StringUtils.isBlank(zwfwUuid) || StringUtils.isBlank(username)) {
                return AjaxResult.error("获取登陆人信息失败");
            }
        } else {
            return AjaxResult.error("获取登陆人信息失败");
        }

        // 判断用户是否存在
        SysUser sysUser = sysUserMapper.checkUserNameUnique(username);
        // 自动登录无需校验密码，并创建token
        if(sysUser != null) {
            String token = loginService.login(sysUser.getUserName(), "", "", "", UserDetailsServiceImpl.AI_SHAN_DONG_SSO_FLAG);
            sysUserMapper.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getUserId, sysUser.getUserId()).set(SysUser::getZwfwUuid, zwfwUuid));
            AjaxResult ajax = AjaxResult.success();
            ajax.put(Constants.TOKEN, token);
            return ajax;
        } else {
            String msg = "";
            // 新建用户
            SysUser user = new SysUser();
            user.setUserName(username);
            user.setNickName(dto.getEnterpriseName());
            String password = username;
            if (username.length() >= 6) {
                password = username.substring(username.length() - 6);
            }
            user.setPassword(SecurityUtils.encryptPassword(password));
            user.setRemark("智慧工信");
            user.setZwfwUuid(zwfwUuid);
            boolean regFlag = sysUserMapper.insertUser(user) > 0;
            if (!regFlag)
            {
                msg = "注册失败,请联系系统管理人员";
            }
            else
            {
                // 查询新的用户id，设置一个普通角色
                Long userId = h5RegisterMapper.queryRegisterUserId(user.getUserName());
                if(userId == null) {
                    msg = "注册失败,请联系系统管理人员";
                }
                else {
                    // 普通角色
                    h5RegisterMapper.insertRegisterUserRole(userId, 2L);
                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(dto.getEnterpriseName(), Constants.REGISTER, MessageUtils.message("user.register.success")));

                }
            }
            if (com.ruoyi.common.utils.StringUtils.isNotEmpty(msg)) {
                return AjaxResult.error(msg);
            } else {
                String token = loginService.login(username, "", "", "", UserDetailsServiceImpl.AI_SHAN_DONG_SSO_FLAG);
                AjaxResult ajax = AjaxResult.success();
                ajax.put(Constants.TOKEN, token);
                ajax.put("isNew", "0");
                ajax.put("uuid", "");
                return ajax;
            }
        }
    }
}
